﻿using HuaCheng.Controller;
using HuaCheng.DataAccess;
using HuaCheng.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HuaCheng.SendAndReceive
{
    class ReceiveClient
    {
        //独立模式参数包
        CommandProtocol.IndependParameter inPara = new CommandProtocol.IndependParameter();
        //并联模式参数包
        CommandProtocol.ParalleParameter paPara = new CommandProtocol.ParalleParameter();
        //独立模式动作包
        CommandProtocol.IndependAction inAction = new CommandProtocol.IndependAction();
        //并联模式动作包
        CommandProtocol.ParalleAction paAction = new CommandProtocol.ParalleAction();
        //并联模式使能包
        CommandProtocol.ParallePulseEner paPulse = new CommandProtocol.ParallePulseEner();
        //接收Socket信息
        public static Socket client;
        //发送用的字节数组
        public byte[] temp;
        //接收数据字节数
        public int i;
        //接收用的字节数组
        public byte[] bytes = new byte[1024];
        //通道状态类
        public ChannelState cs;
        //工步启动时间
        public DateTime beginTime;
        //接收数据包时间
        public DateTime nowTime;
        //单点暂停时间
        public DateTime pauseTime;
        //接续时间
        public DateTime contiTime;
        //开机是否成功
        public bool isOn;
        //关机是否成功
        private bool isClosed;
        //工步号
        int stepNum = 1;
        //循环次数
        public int circ = 0;
        //判断接收线程是否结束
        bool isOver;
        //工步信息列表
        public List<StepInfo> stepList;
        //判断工步是否切换
        bool isChanged;
        //当前工步状态
        string currentState;
        //实际通道号
        int realId;
        //柜号
        int gId;
        //通道号
        int cId;
        //设备号
        string devIp;
        //并联通道号
        List<int> chlList;
        //并联通道状态
        List<ChannelState> csList;
        //保护条件参数
        public Dictionary<string, string> txtNameValue { get; set; }
        //存储当日数据的数据表名
        public string tableName;
        //是否为并联通道
        bool isParalle;
        //前一工布是否为搁置工步
        bool isAfterPause;
        //定义改变通道颜色的委托和事件        
        public delegate void ChangeColor(string c, int r);
        public event ChangeColor ColorChange;
        //定义通道传参的委托和事件
        public delegate void SendParams(string curStat, Channel chl, int r);
        public event SendParams ParamsTransport;
        public Channel chl;
        
        //public delegate void BeforeStart(Channels chls);
        //public event BeforeStart UpdateRunStat;

        ////定义一个内部类 传递参数到主程序
        //public class CloseConnectEventArgs : EventArgs
        //{
        //    public readonly string connIp;//客户端ip
        //    public readonly string connDevType;//客户端设备类型
        //    public readonly bool connStat;//连接状态
        //    public CloseConnectEventArgs(string ip, string type, bool conn)
        //    {
        //        this.connIp = ip;
        //        this.connDevType = type;
        //        this.connStat = conn;
        //    }
        //}
        ////声明委托
        //public delegate void CloseConnectEventHandler(Object sender, CloseConnectEventArgs e);
        ////声明断开连接事件
        //public event CloseConnectEventHandler CloseConnect;
        ////断开连接监听方法
        //public virtual void OnCloseConnect(CloseConnectEventArgs e)
        //{
        //    if (CloseConnect != null)
        //    {
        //        CloseConnect(this, e);
        //    }
        //}
        public ReceiveClient(Socket clientsocket)
        {
            client = clientsocket;
        }
        #region 委托事件
        /// <summary>
        /// 改变颜色
        /// </summary>
        /// <param name="c"></param>
        /// <param name="r"></param>
        public void OnColorChange(string c, int r)
        {
            if (ColorChange != null)
            {
                ColorChange(c, r);
            }
        }
        /// <summary>
        /// 发送数据到IndexPage
        /// </summary>
        /// <param name="curStat"></param>
        /// <param name="chl"></param>
        /// <param name="r"></param>
        public void OnSendParams(string curStat, Channel chl, int r)
        {
            if (ParamsTransport != null)
            {
                ParamsTransport(curStat, chl, r);
            }
        }
        //public void OnBeforeStart(Channels ch)
        //{
        //    if (UpdateRunStat != null)
        //    {
        //        UpdateRunStat(ch);
        //    }
        //}
        #endregion
        #region 接收客户端数据
        /// <summary>
        /// 接收客户端数据
        /// </summary>
        /// <param name="state"></param>
        public void Receive(object state)
        {
            StepSetInfo sp = (StepSetInfo)state;
            if (client != null)
            {
                PrepareReceive(sp);
                if (isOn)
                {
                    beginTime = DateTime.Now;
                    try
                    {
                        //监听用户的单点暂停，接续动作
                        IndexPage.StopByUser += new IndexPage.UserStop(Pause);
                        //异步接收数据
                        AsyncSocketState asyState = new AsyncSocketState(client);
                        asyState.RecvDataBuffer = new byte[client.ReceiveBufferSize];
                        beginTime = System.DateTime.Now;
                        client.BeginReceive(asyState.RecvDataBuffer, 0, asyState.RecvDataBuffer.Length, SocketFlags.None,
                            new AsyncCallback(HandleDataReceived), asyState);                        
                    }
                    catch (System.ObjectDisposedException e)
                    {
                        Console.WriteLine(e.Message);
                    }
                    catch (System.Net.Sockets.SocketException e)
                    {
                        Console.WriteLine(e.Message);
                    }
                    catch (System.ArgumentNullException e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }
        }
        /// <summary>
        /// 接收客户端数据的异步回调委托
        /// </summary>
        /// <param name="ar"></param>
        private void HandleDataReceived(IAsyncResult ar)
        {
            if (!isOver)
            {
                AsyncSocketState asyState = (AsyncSocketState)ar.AsyncState;
                Socket client = asyState.ClientSocket;
                try
                {
                    int recv = client.EndReceive(ar);
                    if (recv == 612)
                    {
                        bytes = asyState.RecvDataBuffer;
                        string first = bytes[0].ToString("X2");
                        string second = bytes[1].ToString("X2");
                        string last = bytes[611].ToString("X2");
                        string secondLast = bytes[610].ToString("X2");
                        if (first == "AA" && second == "55" && last == "AA" && secondLast == "55")
                        {                           
                            cs = CState.byte2Channel(bytes, cId, 76);
                            //接收数据，记录时间
                            nowTime = DateTime.Now;
                            cs.time = nowTime;
                            //开启三个线程
                            ThreadPool.SetMaxThreads(1000, 1000);                                
                            ThreadPool.QueueUserWorkItem(new WaitCallback(SaveData), cs);                           
                            ThreadPool.QueueUserWorkItem(new WaitCallback(StepJudge), stepList);
                            ThreadPool.QueueUserWorkItem(new WaitCallback(ShowView));
                        }
                    }
                }
                catch (SocketException e)
                {

                    Console.WriteLine(e.Message);
                }
                finally
                {
                    if (client != null)
                    {
                        //继续接收来自来客户端的数据
                        client.BeginReceive(asyState.RecvDataBuffer, 0, asyState.RecvDataBuffer.Length, SocketFlags.None,
                            new AsyncCallback(HandleDataReceived), asyState);
                    }
                }
            }
        }
        #endregion
        #region 发送数据给客户端
        /// <summary>
        /// 异步发送指令
        /// </summary>
        /// <param name="state"></param>
        public void Send(byte[] data)
        {
            try
            {
                client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);//无延迟发送
                client.BeginSend(data, 0, data.Length, SocketFlags.None,
                 new AsyncCallback(SendDataEnd), client);
            }
            catch (System.Net.Sockets.SocketException e)
            {
                Console.WriteLine(e.Message);
            }
        }
        /// <summary>
        /// 向客户端发送数据的异步回调委托
        /// </summary>
        /// <param name="ar"></param>
        private void SendDataEnd(IAsyncResult ar)
        {
            ((Socket)ar.AsyncState).EndSend(ar);
            Thread.Sleep(10);
        }
        #endregion
        #region 单点暂停与接续
        public void Pause(bool isStop)
        {
            if (!isParalle)
            {
                //单点暂停
                if (isStop)
                {
                    //记录时间，发送暂停指令
                    pauseTime = DateTime.Now;
                    inAction.stepNum = stepNum - 1;
                    inAction.startPause = CommandProtocol.EStartPauseState.Pause;
                    temp = inAction.Command();
                    Send(temp);
                }
                //接续
                else
                {
                    //记录时间，发送启动指令
                    contiTime = DateTime.Now;
                    inAction.stepNum = stepNum - 1;
                    inAction.startPause = CommandProtocol.EStartPauseState.Start;
                    temp = inAction.Command();
                    Send(temp);
                }
            }
            else
            {
                if (isStop)
                {
                    pauseTime = DateTime.Now;
                    paAction.stepNum = stepNum - 1;
                    paAction.startPause = CommandProtocol.EStartPauseState.Pause;
                    temp = paAction.Command();
                    Send(temp);
                }
                else
                {
                    contiTime = DateTime.Now;
                    paAction.stepNum = stepNum - 1;
                    paAction.startPause = CommandProtocol.EStartPauseState.Start;
                    temp = paAction.Command();
                    Send(temp);
                }

            }

        }
        #endregion
        #region 工步执行前准备工作
        /// <summary>
        /// 工步执行前的准备工作
        /// </summary>
        /// <param name="sp"></param>
        private void PrepareReceive(StepSetInfo sp)
        {
            stepList = sp.StepList;
            realId = sp.RealId;
            gId = sp.Gid;
            cId = sp.Cid;
            devIp = sp.DevIp;
            chlList = sp.ChlList;
            txtNameValue = sp.TxtNameValue;
            chl = sp.chl;
            if (chlList.Count > 0)
            {
                isParalle = true;
            }
            //如果不存在存储当日数据的数据表，则新建数据表
            tableName = ChannelDataHelper.CreateTodayTable(devIp);
            //独立模式
            if (!isParalle)
            {
                inPara.GID = gId;
                inPara.CID = cId;
                inPara.dcBusVoltSet = 0;
                inPara.chEnable = true;
                inPara.isBattery = true;
                inAction.GID = gId;
                inAction.CID = cId;
                inAction.stepNum = stepNum - 1;
                inAction.fan = 1;
                //系统复位
                inAction.systemReset = 1;
                temp = inAction.Command();
                Send(temp);
                //等待100ms后，复位指令撤回
                Thread.Sleep(100);
                inAction.systemReset = 0;
                temp = inAction.Command();
                Send(temp);
                //发送第一条参数指令
                CommandData(0);
                //开机
                inAction.onOff = CommandProtocol.EOnOffState.On;
                temp = inAction.Command();
                Send(temp);
                //监听开机状态
                OpenStateJudge();
                //开机成功
                if (isOn)
                {
                    //开机指令撤回
                    inAction.onOff = CommandProtocol.EOnOffState.Invalid;
                    temp = inAction.Command();
                    Send(temp);
                    //启动指令下达
                    inAction.startPause = CommandProtocol.EStartPauseState.Start;
                    temp = inAction.Command();
                    Send(temp);
                    //等待100ms后，启动指令撤回
                    Thread.Sleep(100);
                    inAction.startPause = CommandProtocol.EStartPauseState.Invalid;
                    temp = inAction.Command();
                    Send(temp);                    
                }
            }
            //并联模式
            else
            {
                paPara.GID = gId;
                paPara.paraMode = 1;
                paPara.paraNum = chlList.Count;
                paPara.shareVolt = chlList.Count;
                paPara.dcBusVoltSet = 0;
                paPara.chEnable = true;
                paPara.isBattery = true;
                paAction.GID = gId;
                paAction.stepNum = stepNum - 1;
                paAction.fan = 1;
                paPulse.GID = gId;
                for (int i = 0; i < chlList.Count; i++)
                {
                    paPara.ch[chlList[i] - 1] = true;
                    paAction.ch[chlList[i] - 1] = true;
                    paPulse.ch[chlList[i] - 1] = true;
                }

                //系统复位
                paAction.systemReset = 1;
                temp = paAction.Command();
                Send(temp);
                //等待100ms后，复位指令撤回
                Thread.Sleep(100);
                paAction.systemReset = 0;
                temp = paAction.Command();
                Send(temp);
                //发送第一条参数指令
                CommandData(0);
                Thread.Sleep(100);
                //开机
                paAction.onOff = CommandProtocol.EOnOffState.On;
                temp = paAction.Command();
                Send(temp);
                //监听开机状态
                OpenStateJudge();
                //开机成功
                if (isOn)
                {
                    //开机指令撤回
                    paAction.onOff = CommandProtocol.EOnOffState.Invalid;
                    temp = paAction.Command();
                    Send(temp);
                    //并联使能包下发
                    paPulse.pulseEn = 1;
                    temp = paPulse.Command();
                    Send(temp);
                    //启动指令下达
                    paAction.startPause = CommandProtocol.EStartPauseState.Start;
                    temp = paAction.Command();
                    Send(temp);
                    //等待100ms后，启动指令撤回
                    Thread.Sleep(100);
                    paAction.startPause = CommandProtocol.EStartPauseState.Invalid;
                    temp = paAction.Command();
                    Send(temp);
                }
            }
        }
        /// <summary>
        /// 开机校验
        /// </summary>
        private void OpenStateJudge()
        {
            beginTime = System.DateTime.Now;
            System.Timers.Timer timeSpan = new System.Timers.Timer(30000);
            timeSpan.Elapsed += (s, ela) =>
            {
                if (!isOn)
                {
                    timeSpan.Close();
                    MessageBox.Show("未接收到校验数据，开机失败");
                }
            };
            timeSpan.AutoReset = true;
            timeSpan.Enabled = true;
            timeSpan.Start();
            try
            {
                while ((i = client.Receive(bytes, 612, 0)) == 612)
                {
                    timeSpan.Close();
                    string first = bytes[0].ToString("X2");
                    string second = bytes[1].ToString("X2");
                    string last = bytes[611].ToString("X2");
                    string secondLast = bytes[610].ToString("X2");
                    if (first == "AA" && second == "55" && last == "AA" && secondLast == "55")
                    {
                        cs = CState.byte2Channel(bytes, cId, 76);
                        //接收数据，记录时间
                        nowTime = System.DateTime.Now;
                        TimeSpan ts = new TimeSpan();
                        TimeSpan maxTime = new TimeSpan(0, 0, 30);
                        ts = nowTime.Subtract(beginTime);
                        if (ts >= maxTime)
                        {
                            MessageBox.Show("DC接触器校验不通过，开机失败");
                            isOn = false;
                            break;
                        }
                        else
                        {
                            if (cs.DCstate1_Contactor == true)
                            {
                                isOn = true;
                                break;
                            }
                        }
                    }
                }
            }
            catch (System.ObjectDisposedException)
            {
                MessageBox.Show("客户端连接已断开");
            }
            catch (System.Net.Sockets.SocketException)
            {

            }
            catch (System.ArgumentNullException)
            {

            }
        }
        #endregion
        #region 结束工步后关机
        /// <summary>
        /// 关机状态监听
        /// </summary>
        private void CloseStateJudge()
        {
            System.Timers.Timer timeSpan = new System.Timers.Timer(10000);
            timeSpan.Elapsed += (s, ela) =>
            {
                if (!isClosed)
                {
                    Send(temp);
                }
                else
                {
                    timeSpan.Close();
                }
            };
            timeSpan.AutoReset = true;
            timeSpan.Enabled = true;
            timeSpan.Start();
            try
            {
                while ((i = client.Receive(bytes, 612, 0)) == 612)
                {
                    string first = bytes[0].ToString("X2");
                    string second = bytes[1].ToString("X2");
                    string last = bytes[611].ToString("X2");
                    string secondLast = bytes[610].ToString("X2");
                    if (first == "AA" && second == "55" && last == "AA" && secondLast == "55")
                    {
                        cs = CState.byte2Channel(bytes, cId, 76);
                        if (cs.DCstate1_Contactor == false)
                        {
                            isClosed = true;
                            //发关机撤回指令
                            if (!isParalle)
                            {
                                inAction.onOff = CommandProtocol.EOnOffState.Invalid;
                                temp = inAction.Command();
                            }
                            else
                            {
                                paAction.onOff = CommandProtocol.EOnOffState.Invalid;
                                temp = paAction.Command();
                            }
                            Send(temp);
                            //StartListen.clientList.Remove(client);
                            //client.Close();
                            break;
                        }
                    }
                }
            }
            catch (System.ObjectDisposedException)
            {
                MessageBox.Show("客户端连接已断开");
            }
            catch (System.Net.Sockets.SocketException)
            {

            }
            catch (System.ArgumentNullException)
            {

            }
        }
        #endregion
        #region 存储数据和通道状态变化线程
        /// <summary>
        /// 存储数据线程
        /// </summary>
        /// <param name="state"></param>
        public void SaveData(object state)
        {
            cs = (ChannelState)state;
            ChannelDataHelper.InsertChannelData(cs,tableName);
        }

        /// <summary>
        /// 通道状态变化线程
        /// </summary>
        /// <param name="state"></param>
        public void ShowView(object state)
        {
            if (isChanged)
            {
                isChanged = false;
                OnColorChange(currentState, realId);//改变通道颜色 
            }     
            string cid = (gId + 1).ToString() + "-" + (cId + 1).ToString();
            chl.ChId = cid;
            chl.DevIp = devIp;
            chl.ChId = cid;//通道号
            chl.StepId = stepNum;//工步序号
            chl.IterId = circ + 1;//循环序号
            TimeSpan ts = new TimeSpan();
            //若该工步被单点暂停过，则不能计算暂停的那段时间
            if (pauseTime != default(DateTime) && contiTime != default(DateTime))
            {
                ts = nowTime.Subtract(contiTime).Add(pauseTime.Subtract(beginTime));
            }
            else
            {
                ts = nowTime.Subtract(beginTime);
            }
            chl.StepTime = ts.ToString().Substring(0, 8);
            chl.Voltage = cs.DC_outputVolt;//电压
            chl.Current = cs.DC_loadCurrent;//电流
            chl.Capacity = cs.chargeCap;//充电容量
            chl.Energy = cs.chargeEnergy;//充电能量
            chl.runStat = true;//设置为运行状态
            OnSendParams(currentState, chl, realId);//传递参数到主程序                  
        }
        #endregion
        #region 工步切换
        /// <summary>
        /// 工步切换线程
        /// </summary>
        /// <param name="state"></param>
        public void StepJudge(object state)
        {
            stepList = (List<StepInfo>)state;
            List<JumpCondition> jcList = new List<JumpCondition>();
            TimeSpan ts = new TimeSpan();
            if (beginTime != default(DateTime))
            {
                //若该工步被单点暂停过，则不能计算暂停的那段时间
                if (pauseTime != default(DateTime) && contiTime != default(DateTime))
                {
                    ts = nowTime.Subtract(contiTime).Add(pauseTime.Subtract(beginTime));
                }
                else
                {
                    ts = nowTime.Subtract(beginTime);
                }
            }
            //当遇到循环工步时，用多个工步顺序执行来代替
            if (stepList[stepNum - 1].StepName != "循环")
            {
                //当前工步存在条件工步子节点时，根据条件工步进行判断
                if (stepList[stepNum - 1].ChildList != null)
                {
                    ConditionJump(stepNum - 1);
                }
                //当前工步不存在条件工步子节点时，根据时间间隔判断，若时间超过，则进入下一工步
                if (stepNum < stepList.Count)
                {
                    TimeSpan stepTime = new TimeSpan(0, 0, 0, 0, (int.Parse(stepList[stepNum - 1].StepTime)));
                    if (ts >= stepTime)
                    {
                        //工步切换，清空单点暂停和解续的时间
                        if (pauseTime != default(DateTime) && contiTime != default(DateTime))
                        {
                            pauseTime = default(DateTime);
                            contiTime = default(DateTime);
                        }
                        stepNum++;
                        beginTime = default(DateTime);
                        CommandData(stepNum - 1);                       
                    }
                }
            }
        }

        /// <summary>
        /// 条件工步判断
        /// </summary>
        /// <param name="index"></param>
        private void ConditionJump(int index)
        {
            List<JumpCondition> jcList = new List<JumpCondition>();
            List<Boolean> multiJc = new List<Boolean>();
            //获取索引为index的节点的所有子节点中如果工步的跳转条件
            for (int i = 0; i < stepList[index].ChildList.Count; i++)
            {
                if (stepList[index].ChildList[i].ChildStepName == "如果")
                {
                    JumpCondition tempStepJumpCondition = new JumpCondition();
                    tempStepJumpCondition.JumpCond = stepList[index].ChildList[i].JumpCond;
                    tempStepJumpCondition.JumpOperator = stepList[index].ChildList[i].JumpOperator;
                    tempStepJumpCondition.JumpValue = Convert.ToSingle(stepList[index].ChildList[i].JumpValue);
                    tempStepJumpCondition.JumpTo = stepList[index].ChildList[i].JumpTo;
                    jcList.Add(tempStepJumpCondition);
                }
            }
            //记录跳转条件是否达成
            bool[] jump = new bool[jcList.Count];
            //遍历条件工步
            for (int j = 0; j < jcList.Count; j++)
            {
                bool finished = false;
                double status = 0;
                //根据跳转条件获取需要比较的状态值
                switch (jcList[j].JumpCond)
                {
                    case "电池电压":
                        status = cs.DC_outputVolt;
                        break;
                    case "电池电流":
                        status = cs.DC_loadCurrent;
                        break;
                }
                //根据操作符判断跳转条件是否达成
                switch (jcList[j].JumpOperator)
                {
                    case ">":
                        {
                            if (status > jcList[j].JumpValue)
                            {
                                jump[j] = true;
                            }
                        } break;
                    case ">=":
                        {
                            if (status >= jcList[j].JumpValue)
                            {
                                jump[j] = true;
                            }
                        } break;
                    case "=":
                        {
                            if (status == jcList[j].JumpValue)
                            {
                                jump[j] = true;
                            }
                        } break;
                    case "<":
                        {
                            if (status < jcList[j].JumpValue)
                            {
                                jump[j] = true;
                            }
                        } break;
                    case "<=":
                        {
                            if (status <= jcList[j].JumpValue)
                            {
                                jump[j] = true;
                            }
                        } break;
                }
                switch (jcList[j].JumpTo)
                {
                    //如果跳转目标为“与（&）”，记录jump，到下一个条件工步
                    case "与(&)":
                        {
                            multiJc.Add(jump[j]);
                            finished = false;
                        } break;
                    //如果跳转目标为不为与，则考虑两种情况。
                    //1.该条件工步与前面的条件工步为“与”关系。遍历multiJc,只要有一个值为false,跳转条件不成立。
                    //2.该条件工步与前面的条件工步为“或”关系或前面没有工步。只要该条件工步成立，则跳转条件成立。
                    default:
                        {
                            if (jump[j] == true)
                            {
                                finished = true;
                                if (multiJc.Count > 0)
                                {
                                    for (int n = 0; n < multiJc.Count; n++)
                                    {
                                        if (multiJc[n] == false)
                                            finished = false;
                                    }
                                }
                                if (finished)
                                {
                                    string[] states = (jcList[j].JumpTo).Split(new Char[] { ':' });
                                    switch (states[1])
                                    {
                                        case "完成":
                                            {
                                                currentState = "完成";
                                                isOver = true;
                                                isChanged = true;
                                                //到达完成状态，通道变化状态
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(ShowView));
                                            } break;
                                        case "保护":
                                            {
                                                currentState = "保护";
                                                isChanged = true;
                                                //到达保护状态，通道变化状态
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(ShowView));
                                            } break;
                                        case "停止":
                                            {
                                                currentState = "停止";
                                                isChanged = true;
                                                //到达停止状态，通道变化状态
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(ShowView));
                                            } break;
                                        default:
                                            {
                                                stepNum = int.Parse(states[1]);
                                                CommandData(stepNum - 1);
                                                beginTime = System.DateTime.Now;
                                            } break;
                                    }
                                }
                            }
                            else
                            {
                                finished = false;
                            }
                            multiJc.Clear();
                        } break;
                }
                if (finished)
                {
                    break;
                }
            }
        }
        #endregion
        #region 数据包组装
        /// <summary>
        /// 数据包组装
        /// </summary>
        /// <param name="index"></param>
        private void CommandData(int index)
        {
            string stepName = stepList[index].StepName;
            switch (stepName)
            {
                case "循环":
                    {
                        if (!isParalle)
                        {
                            inPara.commandUpdata = !inPara.commandUpdata;
                        }
                        else
                        {
                            paPara.commandUpdata = !paPara.commandUpdata;
                        }
                        //获取起始工步号和循环次数
                        int beginIndex = Convert.ToInt32(stepList[index].Voltage) - 1;
                        int circNum = Convert.ToInt32(stepList[index].Cap);
                        circ++;
                        if (circ < circNum)
                        {
                            stepNum = beginIndex + 1;
                            CommandData(stepNum - 1);
                        }
                        else
                        {
                            circ = 0;
                            stepNum++;
                            CommandData(stepNum - 1);
                        }
                    } break;
                case "搁置":
                    {
                        currentState = "搁置";
                        //如果搁置工步的前一工步不为搁置工步，则需发送搁置指令。
                        if (!isAfterPause)
                        {
                            isAfterPause = true;
                            if (!isParalle)
                            {
                                //搁置指令下达
                                inAction.stepNum = stepNum - 1;
                                inAction.startPause = CommandProtocol.EStartPauseState.Pause;
                                temp = inAction.Command();
                                Send(temp);
                            }
                            else
                            {
                                //搁置指令下达
                                paAction.stepNum = stepNum - 1;
                                paAction.startPause = CommandProtocol.EStartPauseState.Pause;
                                temp = paAction.Command();
                                Send(temp);
                            }
                        }
                    } break;
                case "暂停":
                    {
                        currentState = "暂停";
                    } break;
                case "结束":
                    {
                        currentState = "结束";
                        //结束Receive线程
                        isOver = true;
                        isChanged = true;
                        //到达结束工步，通道变化状态
                        ThreadPool.QueueUserWorkItem(new WaitCallback(ShowView));
                        if (!isParalle)
                        {
                            //发送关机指令
                            inAction.stepNum = stepNum - 1;
                            inAction.onOff = CommandProtocol.EOnOffState.Off;
                            inAction.fan = 0;
                            temp = inAction.Command();
                            Send(temp);
                            //判断关机状态
                            CloseStateJudge();
                        }
                        else
                        {
                            //并联使能包撤回
                            paPulse.pulseEn = 0;
                            temp = paPulse.Command();
                            Send(temp);
                            //发送关机指令
                            paAction.stepNum = stepNum - 1;
                            paAction.onOff = CommandProtocol.EOnOffState.Off;
                            paAction.fan = 0;
                            temp = paAction.Command();
                            Send(temp);
                            //判断关机状态
                            CloseStateJudge();
                        }
                    } break;
                default:
                    {
                        //通过CustomStep类拆分工步名称，得到其通道模式，通道波形等信息
                        CustomStep cs = new CustomStep();
                        cs = cs.Spilt(stepName);
                        if (!isParalle)
                        {
                            inPara.stepNum = Convert.ToInt32(stepList[index].StepNum) - 1;
                            inPara.commandUpdata = !inPara.commandUpdata;
                            inPara.voltLimitLower = int.Parse(txtNameValue["txtVMinSP"]);
                            inPara.voltLimitUpper = int.Parse(txtNameValue["txtVMaxSP"]);
                            inPara.currentLimitLower = int.Parse(txtNameValue["txtAMinSP"]);
                            inPara.currentLimitUpper = int.Parse(txtNameValue["txtAMaxSP"]);
                            inPara.temperLimitUpper = int.Parse(txtNameValue["txtTMaxSP"]);
                            inPara.dir = cs.Dir;
                            inPara.modelControl = cs.Model;
                            inPara.waveControl = cs.Wave;
                            SetIndeParam(inPara, cs, index);
                            byte[] temp = inPara.Command();
                            Send(temp);
                            if (isAfterPause)
                            {
                                isAfterPause = false;
                                //启动指令下达
                                inAction.stepNum = stepNum - 1;
                                inAction.startPause = CommandProtocol.EStartPauseState.Start;
                                temp = inAction.Command();
                                Send(temp);
                                Thread.Sleep(100);
                                inAction.startPause = CommandProtocol.EStartPauseState.Invalid;
                                temp = inAction.Command();
                                Send(temp);
                            }
                        }
                        else
                        {
                            paPara.stepNum = Convert.ToInt32(stepList[index].StepNum) - 1;
                            paPara.commandUpdata = !inPara.commandUpdata;
                            paPara.voltLimitLower = int.Parse(txtNameValue["txtVMinSP"]) / chlList.Count;
                            paPara.voltLimitUpper = int.Parse(txtNameValue["txtVMaxSP"]) / chlList.Count;
                            paPara.currentLimitLower = int.Parse(txtNameValue["txtAMinSP"]) / chlList.Count;
                            paPara.currentLimitUpper = int.Parse(txtNameValue["txtAMaxSP"]) / chlList.Count;
                            paPara.temperLimitUpper = int.Parse(txtNameValue["txtTMaxSP"]) / chlList.Count;
                            paPara.dir = cs.Dir;
                            paPara.modelControl = cs.Model;
                            paPara.waveControl = cs.Wave;
                            SetParaParam(paPara, cs, index);
                            temp = paPara.Command();
                            Send(temp);
                            if (isAfterPause)
                            {
                                isAfterPause = false;
                                //启动指令下达
                                paAction.stepNum = stepNum - 1;
                                paAction.startPause = CommandProtocol.EStartPauseState.Start;
                                temp = paAction.Command();
                                Send(temp);
                                Thread.Sleep(100);
                                paAction.startPause = CommandProtocol.EStartPauseState.Invalid;
                                temp = paAction.Command();
                                Send(temp);
                            }
                        }
                        if (cs.Dir)
                        {
                            currentState = "放电";
                        }
                        else
                        {
                            currentState = "充电";
                        }

                    } break;
            }
            isChanged = true;
            beginTime = System.DateTime.Now;
        }

        /// <summary>
        /// 并联模式数据包通道指令参数设置
        /// </summary>
        /// <param name="temp_StepDataIP"></param>
        /// <param name="type"></param>
        /// <param name="index"></param>
        private void SetParaParam(CommandProtocol.ParalleParameter paPara, CustomStep cs, int index)
        {
            ClearParaParam(paPara);
            int count = chlList.Count;
            switch (cs.Type)
            {
                //恒阻模式的参数设置
                case 1:
                    {
                        paPara.param1 = Convert.ToSingle(stepList[index].LoadResistor);
                    } break;
                //恒压恒流模式的参数设置
                case 2:
                    {
                        paPara.param1 = Convert.ToSingle(stepList[index].Current) / count;
                        paPara.param3 = Convert.ToSingle(stepList[index].Voltage);
                    } break;
                //恒流阶跃模式的参数设置
                case 3:
                    {
                        paPara.param1 = Convert.ToSingle(stepList[index].Current) / count;
                    } break;
                //恒压阶跃模式的参数设置
                case 4:
                    {
                        paPara.param1 = Convert.ToSingle(stepList[index].Voltage);
                    } break;
                //恒功率阶跃模式的参数设置
                case 5:
                    {
                        paPara.param1 = Convert.ToSingle(stepList[index].Power) / count;
                    } break;
                //恒流或恒压斜坡模式的参数设置
                case 6:
                    {
                        //恒流斜坡模式
                        if (cs.Model == 0)
                        {
                            paPara.param1 = Convert.ToSingle(stepList[index].BeginValue) / count;
                            paPara.param2 = Convert.ToUInt16(stepList[index].Slope);
                            paPara.param3 = Convert.ToSingle(stepList[index].EndValue) / count;
                        }
                        //恒压斜坡模式
                        else
                        {
                            paPara.param1 = Convert.ToSingle(stepList[index].BeginValue);
                            paPara.param2 = Convert.ToUInt16(stepList[index].Slope);
                            paPara.param3 = Convert.ToSingle(stepList[index].EndValue);
                        }
                    } break;
                //恒流或恒压脉冲模式的参数设置
                case 7:
                    {
                        //恒流斜坡模式
                        if (cs.Model == 0)
                        {
                            paPara.param1 = Convert.ToSingle(stepList[index].Amplitude1) / count;
                            paPara.param2 = Convert.ToUInt16(stepList[index].Time1);
                            paPara.param3 = Convert.ToSingle(stepList[index].Amplitude2) / count;
                            paPara.param4 = Convert.ToUInt16(stepList[index].Time2);
                        }
                        //恒压斜坡模式
                        else
                        {
                            paPara.param1 = Convert.ToSingle(stepList[index].Amplitude1);
                            paPara.param2 = Convert.ToUInt16(stepList[index].Time1);
                            paPara.param3 = Convert.ToSingle(stepList[index].Amplitude2);
                            paPara.param4 = Convert.ToUInt16(stepList[index].Time2);
                        }
                    } break;
            }
            if (cs.Dir)
            {
                paPara.param1 = -paPara.param1;
                paPara.param2 = -paPara.param2;
                paPara.param3 = -paPara.param3;
                paPara.param4 = -paPara.param4;
            }

        }

        /// <summary>
        /// 清空并联模式数据包的通道指令参数
        /// </summary>
        /// <param name="paPara"></param>
        private void ClearParaParam(CommandProtocol.ParalleParameter paPara)
        {
            paPara.param1 = 0;
            paPara.param2 = 0;
            paPara.param3 = 0;
            paPara.param4 = 0;
        }

        /// <summary>
        /// 独立模式数据包通道指令参数设置
        /// </summary>
        /// <param name="inPara"></param>
        /// <param name="type"></param>
        /// <param name="index"></param>
        private void SetIndeParam(CommandProtocol.IndependParameter inPara, CustomStep cs, int index)
        {
            ClearIndeParam(inPara);
            switch (cs.Type)
            {
                //恒阻模式的参数设置
                case 1:
                    {
                        inPara.param1 = Convert.ToSingle(stepList[index].LoadResistor);
                    } break;
                //恒压恒流模式的参数设置
                case 2:
                    {
                        inPara.param1 = Convert.ToSingle(stepList[index].Current);
                        inPara.param3 = Convert.ToSingle(stepList[index].Voltage);
                    } break;
                //恒流阶跃模式的参数设置
                case 3:
                    {
                        inPara.param1 = Convert.ToSingle(stepList[index].Current);
                    } break;
                //恒压阶跃模式的参数设置
                case 4:
                    {
                        inPara.param1 = Convert.ToSingle(stepList[index].Voltage);
                    } break;
                //恒功率阶跃模式的参数设置
                case 5:
                    {
                        inPara.param1 = Convert.ToSingle(stepList[index].Power);
                    } break;
                //恒流或恒压斜坡模式的参数设置
                case 6:
                    {
                        inPara.param1 = Convert.ToSingle(stepList[index].BeginValue);
                        inPara.param2 = Convert.ToUInt16(stepList[index].Slope);
                        inPara.param3 = Convert.ToSingle(stepList[index].EndValue);
                    } break;
                //恒流或恒压脉冲模式的参数设置
                case 7:
                    {
                        inPara.param1 = Convert.ToSingle(stepList[index].Amplitude1);
                        inPara.param2 = Convert.ToUInt16(stepList[index].Time1);
                        inPara.param3 = Convert.ToSingle(stepList[index].Amplitude2);
                        inPara.param4 = Convert.ToUInt16(stepList[index].Time2);
                    } break;
            }
            if(cs.Dir)
            {
                inPara.param1 = -inPara.param1;
                inPara.param2 = -inPara.param2;
                inPara.param3 = -inPara.param3;
                inPara.param4 = -inPara.param4;
            }
        }

        /// <summary>
        /// 清空独立模式数据包的通道指令参数
        /// </summary>
        /// <param name="inPara"></param>
        private static void ClearIndeParam(CommandProtocol.IndependParameter inPara)
        {
            inPara.param1 = 0;
            inPara.param2 = 0;
            inPara.param3 = 0;
            inPara.param4 = 0;
        }
        #endregion
    }
}
